//--------------------------------------------------------------
// #Subject: wur's javascript library
// #Description: It's should be renamed to "basic.js". It's about bacis operates for elements;
// #Creation Date: 
// #Generator: EditPlus2.12
//-------------------------------------------------------------------------------------------------------------------------------


//public functions
function L(o){
	o.g=function(id){return document.getElementById(id);};
	o.c=function(tagName){return document.createElement(tagName);};
	o.fg=function(){return document.createDocumentFragment();};
	o.domToString=function(dom){

		return (dom.outerHTML||function(dom){
			var attr=dom.attributes;
			var ret="<"+dom.tagName;
			for(var i=0;i<attr.length;i++){
				ret+=" "+attr[i].name+"=\""+attr[i].value+"\"";
			}
			ret+=">"+dom.innerHTML+"</"+dom.tagName+">";
			return ret;
		
		}(dom)).toLowerCase();
	};

	o.cancelBubble=function(e){
			if(e===undefined){
				var callor=this.cancelBubble.caller;
				var e=window.event||callor.arguments[0];
			}
			if(e.stopPropagation){
				e.stopPropagation();
			}else{
				e.cancelBubble=true;
			}
	};//事件停止起泡
	o.preventDefault=function(e){
		if(!e)e=this;
		if ( e && e.preventDefault )
			e.preventDefault();
		else
			e.returnValue = false;
		   
		return false; 
	};//事件阻止浏览器默认行为

	o.attrs=function(dom){
		if(dom.attributes.length>60){//60只是个大概的数字,全部属性有70-80个，到100多个不等
			if(dom.outerHTML){
				var s=dom.outerHTML.replace(dom.innerHTML,"");
				var a=s.match(/\w+\=([^\"\s]+|\"[^\"]+\")/g);
				var ret=[];
				for(var i=0;i<a.length;i++){
					var ar=a[i].split("=");
					ret[ret.length]={
						name:ar[0],
						value:ar[1]
					};

				}
				return ret;
			}
		}else{
			return dom.attributes;
		}
	};
	o.trim=function(s){
		return s.replace(/^(\s|\u00A0)+|(\s|\u00A0)+$/g,'');
	};
	return o;
}

L(window);


//键盘对象 键-值对
var keyCode = {
	BACKSPACE: 8,
	CAPS_LOCK: 20,
	COMMA: 188,
	CONTROL: 17,
	DELETE: 46,
	DOWN: 40,
	END: 35,
	ENTER: 13,
	ESCAPE: 27,
	HOME: 36,
	INSERT: 45,
	LEFT: 37,
	NUMPAD_ADD: 107,
	NUMPAD_DECIMAL: 110,
	NUMPAD_DIVIDE: 111,
	NUMPAD_ENTER: 108,
	NUMPAD_MULTIPLY: 106,
	NUMPAD_SUBTRACT: 109,
	PAGE_DOWN: 34,
	PAGE_UP: 33,
	PERIOD: 190,
	RIGHT: 39,
	SHIFT: 16,
	SPACE: 32,
	TAB: 9,
	UP: 38
}
function $(){

}

//Class Dom's constructor
function Dom(tag){
	return this.init(tag);
}
Dom.prototype={
	show:function(){this.style.display="";return this;},
	hide:function(){this.style.display="none";return this;},
	remove:function(){this.parentNode.removeChild(this);return this;},

	addClass:function(cname){
		this.className=this.className?(this.className+" "+cname):cname;
		return this;
	},
	removeClass:function(cname){
		if(cname===undefined){
			this.className="";
			
		}else{
			this.className=this.className.replace(new RegExp("\\s?"+cname+"\\b"),"");
		}
		return this;
	},
	isShow:function(){
		return this.style.display!="none";
	},
	
	bind:function(type,handler){//bind event to element
		if(this.addEventListener){
			this.addEventListerner(type,handler,false)
		}else if(this.attachEvent){
			this.attachEvent("on"+type,handler);
		}
		return this;
	},
	unbind:function(type,handler){
		if(this.removeEventListener){
			this.removeEventListener(type,handler,false);

		}else if(this.detachEvent){
			this.detachEvent("on"+type,handler);
		}
		return this;
	},
	getAttrs:function(){//获得当前元素所有属性
		if(this.outerHTML){
			var reg=new RegExp("<"+this.tagName+"\\s?");
			var s=this.outerHTML.split(">")[0].replace(reg,"").toLowerCase().split(" ");

			var ret=[];
			for(var i=0;i<s.length;i++){

				ret[i]={};
				ret[i].name=s[i].split("=")[0];
				ret[i].value=s[i].split("=")[1];
			}
			return ret;

		}else if(this.attributes){
			return this.attributes;
		}
	},

	init:function(tag){
		var dom=(typeof tag=="object")?tag:document.createElement(tag);
		for(var k in this){
			if(k!="init"){
				dom[k]=this[k];
			}
		}
		return dom;
	}
};

//class table
function Table(oFields,oAttributes){
	return this.init(oFields,oAttributes||{});

};
Table.prototype={
	init:function(oFields,oAttributes){
		var 
		oTable=c("table"),
		oThead=c("thead"),
		oTbody=c("tbody");

		oTable.appendChild(oThead);
		oTable.appendChild(oTbody);


		//set attributs for new table
		for(var k in oAttributes){
			oTable[k]=oAttributes[k];
		}
		
		//fill fields to thead
		var tr=c("tr");
		for(var k in oFields){
			var th=c("th");
			th.innerHTML=oFields[k];
			tr.appendChild(th);
		}

		oThead.appendChild(tr);

		this.tbody=oTbody;

		//extend table
		for(var k in this){
			if(k!="init")oTable[k]=this[k];
		}
		return oTable;

	},
	appendRow:function(oValues){
		var tr=c("tr");
		var frg=fg();
		for (var k in oValues){
			var td=c("td");
			td.innerHTML=oValues[k];
			frg.appendChild(td)
		}
		tr.appendChild(frg);

		this.tbody.appendChild(tr);

	}
};


//Class Select's constructor
function Select(src){
	
	this._init(src);
}
//depends on Class Dom;
Select.prototype={
	_selectingValue:null,//正选择的值，用于click,blur
	_selectedOption:null,//当前选项
	_index:0,
	_now:null,

	onChange:function(){},

	_init:function(src){
		if(src&&src.tagName&&src.tagName=="SELECT"){
			
			var options=src.options;

			var div=new Dom("span");
			div.style.display="inline-block";

			if(src.name){//如果有name属性，用一个hidden代替之
				var hideField=new Dom("input");
				hideField.type="hidden";
				hideField.name=src.name;
				hideField.value=src.value;
				this.hideField=hideField;

				div.appendChild(hideField);
			};


			var sel=this._createSelect(src);
			
			div.appendChild(sel);


			var ul=new Dom("ul");
	
			for(var i=0;i<options.length;i++){
				ul.appendChild(this._createOption(options[i].innerHTML,options[i].value,options[i].selected));
			}

			ul.style.width=src.offsetWidth+"px";
			ul.style.position="absolute";
			ul.hide();
			ul.className="opt"
			div.appendChild(ul);

			this.src=src;
			this.sel=sel;
			this.opt=ul;

			this._setValue(this._selectedOption.innerHTML);//设置初始值

			src.parentNode.replaceChild(div,src);
			

		}
	},
	_createSelect:function(src){

		var sel=new Dom("div");
		sel.tabIndex=0;
		sel.style.height=sel.style.lineHeight=src.offsetHeight+"px";
		sel.style.width=src.offsetWidth+"px";
		sel.className="sel";
		
		if(src.getAttribute("onchange")!=null){
			this.onChange=new Function(src.getAttribute("onchange"));
			//alert(this.onChange+"   on");
		}

		var that=this;

		sel.onmouseover=function(){
			sel.addClass("hover");
		};
		sel.onmouseout=function(){
			sel.removeClass("hover");
		};

		sel.onclick=function(e){

			if(that.opt.isShow()){
				
				that._hideOption();
			}else{
				that._popupOption();
			}

		};


		sel.onblur=function(e){
			that._hideOption();
			that._setValue();
			
		};

		//键盘操作 方向键 IE下只有keydown keyup好用
		sel.onkeydown=function(e){
			e=e||window.event;
			switch(e.keyCode){
				case keyCode.UP:
				that._setStep(-1);
				break;

				case keyCode.DOWN:
				that._setStep(1);
				break;

				case keyCode.ENTER:
				if(that.opt.isShow()){
					that._hideOption();
					that._setStep(0);
				}
				break;

				case keyCode.ESCAPE:
				that._hideOption();
				break;
			}
		};
		return sel;
	},
	_createOption:function(txt,val,isNow){
		var that=this;
		var li=new Dom("li");

		li.setAttribute("index",this._index++);
		
		li.innerHTML=txt;

		if(val===undefined){
			val=txt;//
		}

		li.setAttribute("value",val)

		li.onmousedown=function(e){
			that._selectingValue=this.innerHTML;
			that._selectedOption=this;

		};
		li.onmouseover=function(){
			if(that._now){
				that._now.removeClass("now");	
			}
			that._now=li.addClass("now");;
		};
		if(isNow){
			this._selectedOption=li;

		}
		return li;
	},
	_setValue:function(val){
		if(this._selectingValue){
			var that=this;
			this.sel.innerHTML=this._selectingValue;

			setTimeout(function(){that.sel.focus();},1);
			this._selectingValue=null;	
			this.onChange();
		}else if(val){
			this.sel.innerHTML=val;
			this.onChange();

			
		}else{
			
		}
		if(this.hideField){
			this.hideField.value=this.val();
		}
		
	},
	//设置当前选项 step:-1或1,-1向上移动,1向下移动
	_setStep:function(step){
		if(step<0){
			if(this._now&&this._now.previousSibling){
				this._now.removeClass("now");
				this._now=this._now.previousSibling.addClass("now");
			}else if(!this._now){
				this._now=this.opt.lastChild.addClass("now");
			}
		}else if(step>0){

			if(this._now&&this._now.nextSibling){
				this._now.removeClass("now");
				this._now=this._now.nextSibling.addClass("now");
				
			}else if(!this._now){
				this._now=this.opt.firstChild.addClass("now");
			}
		}else if(step==0){
			
		}
		this._selectedOption=this._now;
		this._setValue(this._now.innerHTML);
		
		
	},
		//参数opt--object
	_setNow:function(opt){//将option对象设置为当前选中
		this._selectedOption=opt;
		this.sel.innerHTML=opt.innerHTML;
		if(this.hideField){
			this.hideField.value=opt.getAttribute("value");
		}
		this.onChange();
		return this;

	},
	_popupOption:function(){//弹出选项
		if(this._now){
			this._now.removeClass("now");
		}
		this._now=this._selectedOption.addClass("now");
		this.opt.show();
	},
	_hideOption:function(){//隐藏选项
		this.opt.hide();
	},
	val:function(){
		if(arguments[0]){//set
			var val=arguments[0];
			var obj=this._selectedOption;
			if(obj.getAttribute("value")!=val){

				var prev=obj,next=obj;
				while(next=next.nextSibling){
					if(next.getAttribute("value")==val){

						return this._setNow(next);
						 
					}
				}

				while(prev=prev.previousSibling){
					if(prev.getAttribute("value")==val){
						
						return this._setNow(prev);
					}
				}
				
			}
			
			return this;
		}else{//get
			return this._selectedOption.getAttribute("value");
		}
	},
	selectedIndex:function(){
		if(arguments[0]===undefined){//get
			return this._selectedOption.getAttribute("index");
		}else if(!isNaN(arguments[0])){//set

			var index=arguments[0];
			var obj=this._selectedOption;
			if(obj.getAttribute("index")!=index){

				var prev=obj,next=obj;

				while(next=next.nextSibling){
					if(next.getAttribute("index")==index){

						return this._setNow(next);
						 
					}
				}

				while(prev=prev.previousSibling){
					if(prev.getAttribute("index")==index){
						
						return this._setNow(prev);
					}
				}
				
			}
			
			return this;
		}
	}

};


//create Tr
function Tr(){
	var tr=new Dom("tr");
	for(var i=0;i<arguments.length;i++){
		var td=new Dom("td");
		td.appendChild(document.createTextNode(arguments[i]));
		tr.appendChild(td);
	}	
	return tr;
}


//class SortTable
/*
	tbody -- Tbody Element
	fieldIndex -- which field. It's td's index
	isString -- if it's true, compare by string, otherwise sort by Number;

*/
function SortTable(tbody,fieldIndex,isString){
	if(!tbody.tagName||tbody.tagName!="TBODY"){throw new Error("SortTable实例化时第一个参数不是tbody");}
	if(!fieldIndex)var fieldIndex=0;
	var isString=!!isString;

	var trs=[];
	
	for(var j=0,items=tbody.getElementsByTagName("tr"),len=items.length;j<len;j++){
		trs[trs.length]=items[j];
	}
	
	
	var fields=[];

	for(var i=0;i<trs.length;i++){
		var td=trs[i].getElementsByTagName("td")[fieldIndex];
		var field=td.textContent||td.innerText;
		
		fields[fields.length]=isString?field:(parseFloat(field));
		
	}
	
	this.onSort=function(){};
	

	this.sort=function(reverse){
		if(!reverse){
			reverse=false;
		}else{
			reverse=true;
		}
		
		//sort fields
		for(var m=0;m<fields.length;m++){

			for(var n=m+1;n<fields.length;n++){
				if((fields[m]>fields[n])==reverse){
					var tmp=fields[m];
					fields[m]=fields[n];
					fields[n]=tmp;

					var tmp=trs[m];
					trs[m]=trs[n];
					trs[n]=tmp;
				}
			}
		}
		
		for(var k=0;k<trs.length;k++){
			tbody.appendChild(trs[k]);
		}
		if(typeof(this.onSort)=="function"){
			this.onSort();
		}
	};


}